package com.sk.ccflower.server.lib.dbUtils;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;

public class DBTransaction {

	private Statement[] m_stmt = null;
	private PreparedStatement[] m_pstmt = null;
	private boolean m_transaction = false;

	public DBTransaction(boolean transaction) {
		m_transaction = transaction;
	}

	public void begin(DBConnection cons) throws SQLException {
		begin(cons, 1);
	}

	public void begin(DBConnection cons, int stmtCnt) throws SQLException {
		end();

		try {
			m_stmt = new Statement[stmtCnt];
			for (int i = 0; i < stmtCnt; i++)
				m_stmt[i] = cons.m_con.createStatement();
		} catch (SQLException ex) {
			rollback();
			end();

			cons.connect(m_transaction, 3);

			try {
				m_stmt = new Statement[stmtCnt];
				for (int i = 0; i < stmtCnt; i++)
					m_stmt[i] = cons.m_con.createStatement();
			} catch (Exception e) {
			}
		}
	}

	public void begin(DBConnection cons, String query) throws SQLException {
		String[] querys = { query };
		begin(cons, querys);
	}

	public void begin(DBConnection cons, String[] querys) throws SQLException {
		end();

		try {
			m_pstmt = new PreparedStatement[querys.length];
			for (int i = 0; i < m_pstmt.length; i++)
				m_pstmt[i] = cons.m_con.prepareStatement(querys[i]);
		} catch (SQLException ex) {
			rollback();
			end();

			cons.connect(m_transaction);

			m_pstmt = new PreparedStatement[querys.length];

			for (int i = 0; i < m_pstmt.length; i++) {
				m_pstmt[i] = cons.m_con.prepareStatement(querys[i]);
			}
		}
	}

	public String clip(String oriMsg, int size) {
		byte[] ob = oriMsg.getBytes();

		if (ob.length > size) {
			byte[] nb = new byte[size];
			System.arraycopy(ob, 0, nb, 0, size);
			return new String(nb);
		} else {
			return oriMsg;
		}
	}

	public void setNullValue(int col) throws SQLException {
		setNullValue(0, col);
	}

	public void setNullValue(int pstmtIdx, int col) throws SQLException {

		m_pstmt[pstmtIdx].setNull(col, Types.NULL);
	}

	public void setValue(int col, char cv) throws SQLException {
		setValue(0, col, cv);
	}

	public void setValue(int pstmtIdx, int col, char cv) throws SQLException {
		m_pstmt[pstmtIdx].setString(col, cv + "");
	}

	public void setValue(int col, int iv) throws SQLException {
		setValue(0, col, iv);
	}

	public void setValue(int pstmtIdx, int col, int iv) throws SQLException {
		m_pstmt[pstmtIdx].setInt(col, iv);
	}

	public void setValue(int col, String str) throws SQLException {
		setValue(0, col, str);
	}

	public void setValue(int col, String str, int size) throws SQLException {
		setValue(0, col, str, size);
	}

	public void setValue(int pstmtIdx, int col, String str) throws SQLException {
		m_pstmt[pstmtIdx].setString(col, str);
	}

	public void setValue(int pstmtIdx, int col, String str, int size)
			throws SQLException {
		m_pstmt[pstmtIdx].setString(col, clip(str, size));
	}

	public void setValue(int col, long lv) throws SQLException {
		setValue(0, col, lv);
	}

	public void setValue(int pstmtIdx, int col, long lv) throws SQLException {
		m_pstmt[pstmtIdx].setLong(col, lv);
	}

	public void setValue(int col, float fv) throws SQLException {
		setValue(0, col, fv);
	}

	public void setValue(int pstmtIdx, int col, float fv) throws SQLException {
		m_pstmt[pstmtIdx].setFloat(col, fv);
	}

	public void setBlobValue(int col, String str) throws SQLException {
		setBlobValue(0, col, str);
	}

	public void setBlobValue(int pstmtIdx, int col, String str)
			throws SQLException {
		InputStream in = new ByteArrayInputStream(str.getBytes());
		m_pstmt[pstmtIdx].setBinaryStream(col, in, str.getBytes().length);
	}

	public void addValue() throws SQLException {
		addValue(0);
	}

	public void addValue(int pstmtIdx) throws SQLException {
		m_pstmt[pstmtIdx].addBatch();
	}

	public int execute(String query) throws SQLException {
		return execute(0, query);
	}

	public int execute(int stmtIdx, String query) throws SQLException {
		return m_stmt[stmtIdx].executeUpdate(query);
	}

	public int execute() throws SQLException {
		return execute(0);
	}

	public int execute(int pstmstIdx) throws SQLException {
		return m_pstmt[pstmstIdx].executeUpdate();
	}

	public int executeBatch() throws SQLException {
		return executeBatch(0);
	}

	public int executeBatch(int pstmtIdx) throws SQLException {
		m_pstmt[pstmtIdx].executeBatch();
		return m_pstmt[pstmtIdx].getUpdateCount();
	}

	public ResultSet selectStmt(String query) throws SQLException {
		return selectStmt(0, query);
	}

	public ResultSet selectStmt(int stmtIdx, String query) throws SQLException {
		return m_stmt[stmtIdx].executeQuery(query);
	}

	public ResultSet selectPstmt() throws SQLException {
		return selectPstmt(0);
	}

	public ResultSet selectPstmt(int pstmtIdx) throws SQLException {
		return m_pstmt[pstmtIdx].executeQuery();
	}

	public void end() {
		if (m_stmt != null) {
			for (int i = 0; i < m_stmt.length; i++) {
				if (m_stmt[i] != null) {
					try {
						m_stmt[i].close();
					} catch (SQLException ex) {
						ex.printStackTrace();
					}
				}
			}
		}

		if (m_pstmt != null) {
			for (int i = 0; i < m_pstmt.length; i++) {
				if (m_pstmt[i] != null) {
					try {
						m_pstmt[i].close();
					} catch (SQLException ex1) {
						ex1.printStackTrace();
					}
				}
			}
		}
	}

	public void end(ResultSet rs) {
		if (rs != null) {
			try {
				rs.close();
				end();
			} catch (SQLException ex) {
				ex.printStackTrace();
			}
		}
		end();
	}

	public void commit() throws SQLException {
		if (m_stmt != null) {
			m_stmt[m_stmt.length - 1].getConnection().commit();
		}

		if (m_pstmt != null) {
			m_pstmt[m_pstmt.length - 1].getConnection().commit();
		}
	}

	public void rollback() {
		if (m_stmt != null) {
			for (int i = 0; i < m_stmt.length; i++) {
				try {
					if (m_stmt[i] != null) {
						m_stmt[i].getConnection().rollback();
					}
				} catch (SQLException ex) {
					ex.printStackTrace();
				}
			}
		}

		if (m_pstmt != null) {
			for (int i = 0; i < m_pstmt.length; i++) {
				try {
					if (m_pstmt[i] != null) {
						m_pstmt[i].getConnection().rollback();
					}
				} catch (SQLException ex) {
					ex.printStackTrace();
				}
			}
		}
	}

}
